
/**
 * OPTIONS: 
 *  outEle: dom元素 指定拖拽的容器 默认是body;
 *  inEle: dom元素 指定需要拖拽的元素 默认是初始化dom
 *  onStart: 拖拽开始的回调 可选
 *  onDrag: 拖拽时候的回调 可选
 *  onEnd: 拖拽结束时回调 可选
 *  使用: 传入 dom
 *  new Tractor(el);
 */
class Tractor {
	isDraggable = false;
	constructor(el, options) {
		let { outEle, inEle, onStart, onDrag, onEnd } = options ?? {};
		this.el = el;
		this.onStart = onStart;
		this.onDrag = onDrag;
		this.onEnd = onEnd;
		this.startTransform = getComputedStyle(el).transform;
		this.startPos = null;
		this.endPos = null;
		this.outEle = outEle ?? document.body;
		this.inEle = inEle ?? el;
		this.draggingVectorRange = null;
		this.dragedVector = [0, 0];
		this.draggingVector = [0, 0];
		this.registryEventsListener();
	}

	onMouseDown(evt) {
		evt.stopPropagation();
		this.startPos = this.getPos(evt);
		if (this.outEle && this.el && this.inEle) {
			this.isDraggable = true;
			this.setStyle(this.el, 'cursor', "pointer")
			const outEleRect = this.outEle.getBoundingClientRect();
			const elRect = this.el.getBoundingClientRect();
			this.draggingVectorRange = [
				outEleRect.top - elRect.top,
				outEleRect.bottom - elRect.bottom,
				outEleRect.left - elRect.left,
				outEleRect.right - elRect.right,
			];
			typeof this.onStart === "function" && this.onStart(this.dragedVector);
		}
	}
	onMouseMove(evt) {
		if (this.isDraggable && this.startPos && this.draggingVectorRange) {
			this.endPos = this.getPos(evt);
			const currMoveVector = this.formatVector(this.sbuVec(this.startPos, this.endPos), this.draggingVectorRange);
			this.draggingVector = this.addVec(this.dragedVector, currMoveVector);
			this.el.style.transform = this.setTranslate(this.startTransform, this.draggingVector);
			typeof this.onDrag === "function" && this.onDrag(this.draggingVector);
		}
	}

	onMouseUp(evt) {
		if (this.startPos && this.draggingVectorRange) {
			this.dragedVector = this.draggingVector;
			typeof this.onEnd === "function" && this.onEnd(this.dragedVector);
		}
		this.startPos = null;
		this.isDraggable = false;
		this.removeEventListener()
	}
	registryEventsListener() {
		if (this.inEle) {
			this.inEle.addEventListener("mousedown", this.onMouseDown.bind(this));
			document.addEventListener("mousemove", this.onMouseMove.bind(this));
			document.addEventListener("mouseup", this.onMouseUp.bind(this));
		}
	}
	removeEventListener() {
		if (this.inEle) {
			this.inEle.removeEventListener("mousedown", this.onMouseDown);
			document.removeEventListener("mousemove", this.onMouseMove);
			document.removeEventListener("mouseup", this.onMouseUp);
		}
	};
	addVec(v1, v2) {
		return [v1[0] + v2[0], v1[1] + v2[1]];
	}
	sbuVec(v1, v2) {
		return [v2[0] - v1[0], v2[1] - v1[1]];
	}
	formatVector(v, range) {
		let x = v[0];
		let y = v[1];
		x = Math.max(x, range[2]);
		x = Math.min(x, range[3]);
		y = Math.max(y, range[0]);
		y = Math.min(y, range[1]);
		return [x, y];
	};
	getPos(evt) {
		if (evt instanceof MouseEvent) {
			return [evt.pageX, evt.pageY];
		}
	}
	setTranslate(transform, vector) {
		return `translate3d(${vector[0]}px, ${vector[1]}px,0px) ${transform.replace("none", "")}`;
	}
	setStyle(el, key, value) {
		if (!(el && el instanceof HTMLElement)) return;
		console.log();
		if (!el.style.hasOwnProperty(key)) return;
		el.style[key] = value;
		return true;
	}
}


export default Tractor;